﻿#include "IICTableWidget.h"
#include "components/IconButton/IconButton.h"
#include "services/tlv/Com/TlvThreadCom.h"
#include "utils/String/regexp.h"
#include "utils/String/hexbin.h"
#include "components/Toast/Toast.h"
#include "services/Task/TlvCmdTask.h"

#include <QHeaderView>
#include <QDebug>

#define COL_DESC 1
#define COL_ADDR 2
#define COL_DATA 3
#define COL_RLEN 4
#define COL_WAIT 5

IICTableWidget::IICTableWidget(QWidget *parent)
    : CustomTableWidget(parent)
{
    // 设置表头
    QStringList headers;
    headers << tr("description") << tr("addr(7bit)") << tr("data") << tr("readLen") << tr("wait(ms)") << tr("send");
    setHeaders(headers);

    // 设置列对齐方式
    setColumnAlignment(COL_DESC, Qt::AlignVCenter | Qt::AlignLeft);     // 描述列左对齐
    setColumnAlignment(COL_ADDR, Qt::AlignVCenter | Qt::AlignHCenter);  // 地址列居中对齐
    setColumnAlignment(COL_DATA, Qt::AlignVCenter | Qt::AlignLeft);     // 数据列左对齐
    setColumnAlignment(COL_RLEN, Qt::AlignVCenter | Qt::AlignHCenter);  // 长度列居中对齐
    setColumnAlignment(COL_WAIT, Qt::AlignVCenter | Qt::AlignHCenter);  // 延时列居中对齐

    // 设置列宽和拉伸模式
    horizontalHeader()->setSectionResizeMode(COL_ADDR, QHeaderView::Fixed);
    setColumnWidth(COL_ADDR, 100);
    horizontalHeader()->setSectionResizeMode(COL_DATA, QHeaderView::Stretch);
    horizontalHeader()->setSectionResizeMode(COL_RLEN, QHeaderView::Fixed);
    setColumnWidth(COL_RLEN, 100);
    horizontalHeader()->setSectionResizeMode(COL_WAIT, QHeaderView::Fixed);
    setColumnWidth(COL_WAIT, 100);

    enableCellKeyEnterCallButton(true);

    connect(this, &IICTableWidget::buttonClicked, this, &IICTableWidget::sendIIC);
}

void IICTableWidget::addIICCmd(const QString& desc, const QString &addr, const QString &data, const QString &readLen, const QString &waitMs)
{
    insertIICCmd(rowCount(), desc, addr, data, readLen, waitMs);
}

void IICTableWidget::addIICCmd(const QString& desc, uint8_t addr, const QByteArray &data, uint8_t readLen, uint16_t waitMs)
{
    addIICCmd(desc, QString::number(addr, 16).toUpper(), data.toHex(' ').toUpper(), QString::number(readLen), QString::number(waitMs));
}

void IICTableWidget::addIICCmd(const QString &desc, const IIC &iic, const QString &waitMs)
{
    addIICCmd(desc, iic, waitMs.toUInt());
}

void IICTableWidget::addIICCmd(const QString &desc, const IIC &iic, uint16_t waitMs)
{
    addIICCmd(desc, iic.slave(), iic.data(), iic.readLen(), waitMs);
}

void IICTableWidget::addNewLine()
{
    addIICCmd("", "", "", "");
}

void IICTableWidget::insertNewLine(int row)
{
    insertIICCmd(row, "", "", "", "");
}

bool IICTableWidget::getRowIIC(int row, IIC *oIic, uint16_t *oWaitMs)
{
    if (row < 0 || row >= rowCount()) return false;
    bool ok = true;
    if (oIic) {
        uint8_t addr = cellText(row, COL_ADDR).toUInt(&ok, 16);
        if (!ok) {
            Toast::warning(tr("[row %1] IIC slave addr cannot be empty!").arg(row));
            return false;
        }
        QByteArray data = HexBin::parseHexString(cellText(row, COL_DATA), &ok);
        // if (!ok || data.isEmpty()) {
        if (!ok) {  // IIC 数据可以为空
            Toast::warning(tr("[row %1] IIC data is invalid, please check it!").arg(row));
            return false;
        }
        uint16_t readLen = cellText(row, COL_RLEN).toUInt(&ok, 10);
        if (!ok) readLen = 0;
        *oIic = IIC(addr, data, readLen);
    }
    if (oWaitMs) {
        uint16_t waitMs = cellText(row, COL_WAIT).toUInt(&ok, 10);
        if (!ok) return false;
        *oWaitMs = waitMs;
    }
    return true;
}

QString IICTableWidget::onPasteHexCallback(const QString &input)
{
    bool ok = true;
    QString res = HexBin::normalizeHexString(input, &ok);
    if (!ok) {
        Toast::error(tr("Hex Data Formate is Wrong!"));
    }
    return res;
}

QList<IICCmdModel> IICTableWidget::toIICCmdModel()
{
    QList<IICCmdModel> res;
    for (int i = 0; i < rowCount(); i++) {
        IICCmdModel model;
        model.title = cellText(i, COL_DESC);
        model.value.addr = cellText(i, COL_ADDR);
        model.value.hexstring = cellText(i, COL_DATA);
        model.value.readlen = cellText(i, COL_RLEN);
        model.wait = cellText(i, COL_WAIT);
        res.push_back(model);
    }
    return res;
}

void IICTableWidget::sendIIC(int row)
{
    IIC iic = IIC::iicNull();
    if (!getRowIIC(row, &iic, nullptr)) {
        return;
    }
    TlvThreadCom::instance()->write(iic);
}

bool IICTableWidget::sendSelected()
{
    QList<IICSend_t> cmds;
    for (int i = 0; i < rowCount(); i++) {
        if (!isRowChecked(i)) continue;
        IICSend_t cmd;
        if (!getRowIIC(i, &cmd.iic, &cmd.wait)) {
            return false;
        }
        cmds.push_back(cmd);
    }
    TlvCmdTask::instance()->setRunIICCmds(cmds);
    TlvCmdTask::instance()->start();
    return true;
}

void IICTableWidget::insertIICCmd(int row, const QString &desc, const QString &addr, const QString &data, const QString &readLen, const QString &waitMs)
{
    // 添加数据
    QStringList rowData;
    rowData << desc << addr << data << readLen << waitMs;

    IconButton* btnSend = new IconButton(this, QIcon(":/imgs/send.png"), "", IconButton::Small);
    insertRow(row, rowData, btnSend);

    int r = rowCount() - 1;
    setCellValidator(r, COL_ADDR, new QRegExpValidator(QRegExp(REGEXP_HEX_LL(2)), this));  // 地址
    setCellValidator(r, COL_DATA, new QRegExpValidator(QRegExp(REGEXP_HEX_SP),    this));  // 数据
    setCellValidator(r, COL_RLEN, new QRegExpValidator(QRegExp(REGEXP_DEC_LL(3)), this));  // 长度
    setCellValidator(r, COL_WAIT, new QRegExpValidator(QRegExp(REGEXP_DEC_LL(4)), this));  // 延时

    setCellPasteCallback(r, COL_DATA, &IICTableWidget::onPasteHexCallback);
}
